/* eslint-disable no-unused-vars */
import React, { memo, useState, useEffect, useRef, useCallback } from "react";
import Taro, { useRouter, useReady, usePageScroll, useShareAppMessage, useShareTimeline } from "@tarojs/taro";
import { useSelector, useDispatch, shallowEqual } from "react-redux";
import { updateState } from "@/store/actions/global";
import { View, Text, Image, Button, Textarea } from "@tarojs/components";
import { Icon, Empty, Rate, Field } from "@antmjs/vantui";
import debounce from "lodash/debounce";
import axios from "@/axios";
import {
  getRecipeDetail,
  getRecipeMaterial,
  getRecipeStep,
  getRecipeComment,
  addRecipeHeat,
  addRecipeMsg,
  delRecipeMsg,
  updateMsgThumb,
  userOpRecipe
} from "@/axios/api/recipe";
import {
  updateRelationShip
} from "@/axios/api/user";
import Authorization from "@/components/Authorization";
import BasketNav from "@/components/BasketNav";
import BackTop from "@/components/BackTop";
import Navbar from "@/components/Navbar";
import toast from "@/utils/toast";
import "@tarojs/taro/html.css";
import "./index.less";
import { themeColor } from "../../utils/config";

const Index = () => {
  const router = useRouter();
  const { recipe_id } = router.params;
  const { globalData } = useSelector(
    (state) => ({ globalData: state.globalData }),
    shallowEqual
  );
  const { isLogin, showBackTop, userInfo, basket, systemInfo } = globalData;
  const { screenHeight } = systemInfo;
  const user_id = userInfo && userInfo.user_id;
  const [recipeData, setRecipeData] = useState({});
  const [isLarge, setIsLarge] = useState(false);
  const [materialData, setMaterialData] = useState([]);
  const [stepData, setStepData] = useState([]);
  const [commentData, setCommentData] = useState([]);
  const [quantityData, setQuantityData] = useState([
    {
      id: 0,
      text: "× 0.5",
      amount: 0.5,
      active: false,
    },
    {
      id: 1,
      text: "标准",
      amount: 1,
      active: true,
    },
    {
      id: 2,
      text: "× 2",
      amount: 2,
      active: false,
    },
    {
      id: 3,
      text: "× 3",
      amount: 3,
      active: false,
    },
  ]);
  const [basketPosition, setPosition] = useState({
    show: false,
    bounce: false,
    ball: {
      w: Taro.pxTransform(20),
      h: Taro.pxTransform(20),
    },
    target: {
      left: 0,
      right: 0,
    },
    clientX: 0,
    clientY: 0,
  });
  const [showInput, setShowInput] = useState(false);
  const scrollTop = useRef();
  const [currentAmount, setCurrentAmount] = useState(1);
  const [inputValue, setInputValue] = useState({
    target: null,
    username: '',
    value: ""
  })
  const dispatch = useDispatch();
  useEffect(() => {
    if (!isLogin) {
      dispatch(
        updateState({
          isShowGrant: true,
        })
      );
      return;
    }
    dispatch(
      updateState({
        showBackTop: false,
      })
    );
    getDetail();
    getMaterial();
    getStep();
    getComment();
    axios.post(addRecipeHeat, { recipe_id }).then();
    return () => {
      dispatch(
        updateState({
          showBackTop: false,
        })
      );
    };
  }, [isLogin, dispatch]);
  useEffect(() => {
    const { target, show } = basketPosition;
    if (show) {
      setTimeout(() => {
        setPosition((pre) => {
          console.log("target");
          return {
            ...pre,
            clientX: target.left,
            clientY: target.top + scrollTop.current,
          };
        });
        setTimeout(() => {
          setPosition((pre) => {
            return {
              ...pre,
              ...{ show: false },
            };
          });
        }, 700);
        setTimeout(() => {
          setPosition((pre) => {
            return {
              ...pre,
              ...{ bounce: false },
            };
          });
        }, 1000);
      }, 0);
    }
  }, [basketPosition.show]);
  const enlarge = () => {
    setIsLarge((pre) => !pre);
  };
  const removeRepeat = (arr) => {
    const hash = {};
    const newArray = arr.reduce((item, next) => {
      hash[next.recipe_id]
        ? ""
        : (hash[next.recipe_id] = true && item.push(next));
      return item;
    }, []);
    return newArray;
  };
  const getCurrentDate = () => {
    let now = new Date();
    let year = now.getFullYear(); //得到年份
    let month = now.getMonth();//得到月份
    let date = now.getDate();//得到日期
    let hour = now.getHours();//得到小时
    let minu = now.getMinutes();//得到分钟
    let sec = now.getSeconds();//得到秒
    month = month + 1;
    if (month < 10) month = "0" + month;
    if (date < 10) date = "0" + date;
    if (hour < 10) hour = "0" + hour;
    if (minu < 10) minu = "0" + minu;
    if (sec < 10) sec = "0" + sec;
    let time = "";
    //精确到分
    time = year + "-" + month + "-" + date + " " + hour + ":" + minu + ":" + sec;
    return time;
  }
  const getDetail = () => {
    axios
      .get(getRecipeDetail, { params: { recipe_id, user_id } })
      .then((res) => {
        const { data, code } = res;
        if (code === 200) {
          setRecipeData(data);
          console.log("detail", data);
          if (data.category) {
            const cats = data.category.split(",");
            let item = cats[Math.floor(Math.random() * cats.length)];
            let hobby = Taro.getStorageSync("hobby");
            if (!hobby) {
              hobby = [];
            }
            if (hobby.length > 99) {
              hobby.pop();
            }
            hobby.unshift(item);
            Taro.setStorageSync("hobby", hobby);
          }
          let history = Taro.getStorageSync("history");
          if (!history) {
            history = [];
          }
          if (history.length > 30) {
            history.pop();
          }
          let date = getCurrentDate();
          console.log(date);
          data.date = date;
          history.unshift(data);
          Taro.setStorageSync("history", removeRepeat(history));
        }
      });
  };
  const getMaterial = () => {
    axios.get(getRecipeMaterial, { params: { recipe_id } }).then((res) => {
      const { data, code } = res;
      if (code === 200) {
        setMaterialData(data.list);
        console.log("material", data);
      }
    });
  };
  const getStep = () => {
    axios.get(getRecipeStep, { params: { recipe_id } }).then((res) => {
      const { data, code } = res;
      if (code === 200) {
        setStepData(data.list);
      }
    });
  };
  const getComment = () => {
    axios
      .get(getRecipeComment, { params: { recipe_id, user_id } })
      .then((res) => {
        const { data, code } = res;
        if (code === 200) {
          setCommentData(data.CommentList);
        }
      });
  };
  const handleThumb = useCallback(
    debounce(
      (node, type) => {
        const { comment_id } = node;
        axios.post(updateMsgThumb, { comment_id, user_id }).then(res => {
          if (res.code === 200) {
            if (type === "father") {
              setCommentData((pre) => {
                const next = pre.map((item) => {
                  if (item.comment_id === node.comment_id) {
                    if (item.state === 0) {
                      item.state = 1;
                      item.thumbs += 1;
                    } else {
                      item.state = 0;
                      item.thumbs -= 1;
                    }
                  }
                  return item;
                });
                return next;
              });
            } else if (type === "child") {
              setCommentData((pre) => {
                const next = pre.map((item) => {
                  const { children } = item;
                  children &&
                    children.forEach((child) => {
                      if (child.comment_id === node.comment_id) {
                        if (child.state === 0) {
                          child.state = 1;
                          child.thumbs += 1;
                        } else {
                          child.state = 0;
                          child.thumbs -= 1;
                        }
                      }
                    });
                  return item;
                });
                return next;
              });
            }
          }
        })
      },
      200,
      {
        leading: true,
        trailing: false,
      }
    ),
    []
  );
  const handleQuantity = (amount, id) => {
    setQuantityData((data) => {
      return data.map((item) => {
        if (item.id === id) {
          item.active = true;
        } else {
          item.active = false;
        }
        return item;
      });
    });
    setCurrentAmount(amount);
  };
  const joinBasket = (type, amount, { detail }) => {
    console.log(type, amount, detail);
    if (type === "join") {
      if (basketPosition.bounce) {
        return;
      }
      let material = [];
      materialData.forEach((item) => {
        let { material_amount, material_index, material_name, material_unit } =
          item;
        material_amount = material_amount ? material_amount * amount : null;
        material.push({
          material_index,
          material_name,
          material_amount,
          material_unit,
          isCheck: false,
        });
      });
      let data = {
        recipe_id,
        timestamp: new Date().getTime(),
        isOpen: false,
        title,
        material,
      };
      if (!basket) {
        basket = [];
      } else if (basket.length > 9) {
        Taro.showModal({
          title: "提示",
          content: `菜篮子已经装不下啦`,
          showCancel: false,
        });
        return;
      }
      basket.unshift(data);
      const query = Taro.createSelectorQuery();
      query
        .select(".basket-position")
        .boundingClientRect((res) => {
          const { left, top, width, height } = res;
          const obj = {
            target: {
              left: left + width / 2,
              top: top + height / 2,
            },
            show: false,
          };
          console.log("target", obj);
          setPosition((pre) => {
            return {
              ...pre,
              ...obj,
            };
          });
          Taro.setStorageSync("basket", basket);
          Taro.setStorageSync("basketUpdate", true);
          dispatch(
            updateState({
              basket,
              basketUpdate: true,
            })
          );
          setPosition((pre) => {
            return {
              ...pre,
              ...{
                show: true,
                bounce: true,
                clientX: detail.x,
                clientY: detail.y,
              },
            };
          });
        })
        .exec();
    } else if (type === "remove") {
      basket.splice(
        basket.findIndex((i) => i.recipe_id === recipe_id),
        1
      );
      Taro.setStorageSync("basket", basket);
      dispatch(
        updateState({
          basket,
        })
      );
    }
  };
  const changeRate = ({ detail }) => {
    setRecipeData((pre) => {
      return {
        ...pre,
        user_score: detail * 2
      }
    });
    updateRate(detail);
  }
  const updateRate = useCallback(
    debounce(
      (value) => {
        handleUserOpRecipe(3, value * 2)
      },
      1000
    ),
    []
  );
  const handleUserOpRecipe = (type, score) => {
    axios.post(userOpRecipe, { recipe_id, user_id, type, score }).then(res => {
      if (res.code === 200) {
        getDetail();
      }
    })
  }
  const jumpTo = (url) => {
    Taro.navigateTo({
      url,
    });
  };
  const handleClick = useCallback(
    debounce(
      (type, id, username) => {
        if (type === 1) {
          handleUserOpRecipe(type);
        } else if (type === 2) {
          handleUserOpRecipe(type);
        } else if (type === 3) {
          setShowInput(true);
        } else if (type === "user") {
          let url = `/pages/userCenter/index?user_id=${id}&username=${username}`;
          jumpTo(url);
        }
      },
      200,
      {
        leading: true,
        trailing: false,
      }
    ),
    [isLogin]
  );
  const handleFollow = useCallback(
    debounce(
      (follow_id, item) => {
        const { state, username } = item;
        console.log({ follow_id, user_id });
        if (state !== 0) {
          Taro.showModal({
            title: '提示',
            content: `你确定要取消关注用户\r\n"${username}"吗`,
            success: function (res) {
              if (res.confirm) {
                axios.post(updateRelationShip, { follow_id, user_id }).then(res => {
                  if (res.code === 200) {
                    const { state } = res.data;
                    setRecipeData(pre => {
                      pre.follow_state = state;
                      return { ...pre }
                    })
                  }
                })
              }
            }
          })
        } else {
          axios.post(updateRelationShip, { follow_id, user_id }).then(res => {
            if (res.code === 200) {
              const { state } = res.data;
              setRecipeData(pre => {
                pre.follow_state = state;
                return { ...pre }
              })
            }
          })
        }
      },
      300,
      {
        leading: true,
        trailing: false,
      }
    ),
    []
  );
  const addMsg = ({ value, target }) => {
    if (value.trim() === '') {
      return;
    }
    axios.post(addRecipeMsg, { recipe_id, user_id, parent_id: target, content: value }).then(res => {
      if (res.code === 200) {
        getComment();
      }
    })
  }
  const delMsg = (comment_id) => {
    Taro.showModal({
      title: '提示',
      content: `你确定要删除这条评论吗？`,
      success: function (res) {
        if (res.confirm) {
          axios.post(delRecipeMsg, { comment_id }).then(res => {
            if (res.code === 200) {
              getComment();
            }
          })
        }
      }
    })
  }
  usePageScroll((res) => {
    const flag = res.scrollTop > screenHeight * 1.5;
    scrollTop.current = res.scrollTop;
    if (flag !== showBackTop) {
      dispatch(
        updateState({
          showBackTop: flag,
        })
      );
    }
  });
  useReady(() => {
    scrollTop.current = 0;
  });
  useShareAppMessage(res => {
    if (res.from === 'button') {
      // 来自页面内转发按钮
      console.log(res.target)
    }
    const { title, recipe_id, image } = recipeData;
    return {
      title: `「${title}」`,
      path: `pages/recipeInfo/index?recipe_id=${recipe_id}`,
      imageUrl: image
    }
  })
  useShareTimeline(() => {
    const { title, recipe_id, image } = recipeData;
    return {
      title: `「${title}」`,
      query: {
        recipe_id
      },
      imageUrl: image
    }
  })
  const {
    image,
    title,
    difficulty,
    is_thumb,
    score,
    thumbs,
    tip,
    total_heat,
    update_time,
    create_time,
    is_collected,
    user_score,
    username: author,
    follow_state,
    avatar,
    map_url,
    showTabbar = 1
  } = recipeData;
  let isInBasket = false;
  let Loading = Object.keys(recipeData).length;
  isInBasket =
    basket &&
    basket.some((item) => {
      if (item.recipe_id === recipe_id) {
        return true;
      }
    });
  const { clientX, clientY, ball, show, target } = basketPosition;
  return (
    <View className='index'>
      <Authorization canClose={false}></Authorization>
      <Navbar title='' arrow='true'></Navbar>
      <View className='basket-position' style={{ top: .75 * screenHeight }}></View>
      <View>
        {show ? (
          <View
            className='ball'
            style={{
              left: clientX,
              top: clientY,
              height: ball.h,
              width: ball.w,
            }}
          ></View>
        ) : null}
      </View>
      <View className={`basket ${basketPosition.bounce ? "anim" : ""}`}>
        <BasketNav top={.75 * screenHeight} />
      </View>
      <View>{showBackTop ? <BackTop top={.75 * screenHeight} /> : null}</View>
      {(Loading&&showTabbar)?<View className='tabbar'>
        <View className='container'>
          <View className='item' onClick={() => { handleClick(1) }}>
            <Icon name={is_thumb ? 'good-job' : 'good-job-o'} size='50' color='#ee0a24'></Icon> <Text decode>{is_thumb ? '已点赞' : `点赞&emsp;`}</Text>
          </View>
          <View className='item' onClick={() => { handleClick(2) }}>
            <Icon name={is_collected ? 'like' : 'like-o'} size='50' color='#ee0a24'></Icon> <Text decode>{is_collected ? '已收藏' : `收藏&emsp;`}</Text>
          </View>
          <View className='item' onClick={() => { handleClick(3) }}>
            <Icon name='chat-o' size='50'></Icon> <Text>评论</Text>
          </View>
          <Button className='item' openType='share' hoverClass='no-hover'>
            <Icon name='share-o' size='50'></Icon> <Text>分享</Text>
          </Button>
        </View>
      </View>
      :null}
      <View>
        {(showTabbar&&showInput)?<View className='message-input'>
          <View className='container'>
            <Textarea
              value={inputValue.value}
              placeholder={inputValue.target ? '@' + inputValue.username + ":" : '写评论...'}
              focus
              autoHeight
              cursorSpacing={50}
              disableDefaultPadding
              maxlength={100}
              onConfirm={() => {
                addMsg(inputValue);
              }}
              onInput={(e) => {
                setInputValue((pre) => {
                  return {
                    ...pre,
                    value: e.detail.value,
                  }
                })
              }}
              onBlur={() => {
                setShowInput(false);
                setInputValue({
                  target: null,
                  username: '',
                  value: ''
                })
              }}
            />

            <View className='btn-submit' onClick={() => {
              addMsg(inputValue);
              setInputValue({
                target: null,
                username: '',
                value: ''
              })
            }}
            >
              提交
          </View>
          </View>
        </View>:null}
      </View>
      <View className='recipe-info'>
        <View className='m-image'>
          <Image
            src={image}
            mode={isLarge ? "widthFix" : "aspectFill"}
            onClick={enlarge}
          />
        </View>
        {Loading ? (
          <>
            <View className='m-title'>
              <Text>{title}</Text>
            </View>
            <View className='m-desc'>
              <Text>{score ? score : "暂无评"}分</Text>
              <Text>{thumbs}人点赞</Text>
              <Text>{difficulty ? "难度:" + difficulty : ""}</Text>
            </View>
            <View className='hr'></View>
            <View className='m-author'>
              <Image src={avatar} onClick={() => handleClick('user', recipeData.user_id, author)} />
              <Text className='name' onClick={() => handleClick('user', recipeData.user_id, author)} >{author}</Text>
              {user_id !== recipeData.user_id &&
                <View className={`btn-follow ${follow_state !== 0 ? 'disable' : ''}`} onClick={() => handleFollow(recipeData.user_id, {
                  username: author,
                  state: follow_state
                })}><Text>{follow_state === 0 ? '关 注' : (follow_state === 1 ? '已关注' : '互相关注')}</Text></View>}
            </View>
            <View className='m-material'>
              <View className='top'>
                <Text>—食材清单—</Text>
              </View>
              {materialData.length ? (
                <>
                  <View className='join-basket'>
                    {isInBasket ? (
                      <Text
                        onClick={(e) => {
                          joinBasket("remove", currentAmount, e);
                        }}
                      >
                        移出菜篮子
                      </Text>
                    ) : (
                        <Text
                          onClick={(e) => {
                            joinBasket("join", currentAmount, e);
                          }}
                        >
                          加入菜篮子
                        </Text>
                      )}
                  </View>
                  <View className='list'>
                    {materialData.map((item) => {
                      return (
                        <View className='item' key={item.material_index}>
                          <Text className='name'>{item.material_name}</Text>
                          <Text className='value'>
                            <Text
                              className='amount'
                              style={{
                                color: currentAmount === 1 ? "" : themeColor,
                              }}
                            >
                              {item.material_amount
                                ? item.material_amount * currentAmount
                                : null}
                            </Text>
                            {item.material_unit}
                          </Text>
                        </View>
                      );
                    })}
                    {map_url === null ? (
                      <View className='btn-group'>
                        <Text className='quantity'>份量：</Text>
                        {quantityData.map((item, index) => {
                          return (
                            <View
                              className={["btn-q", item.active ? "active" : ""]}
                              onClick={() =>
                                handleQuantity(item.amount, item.id)
                              }
                              key={index}
                            >
                              {item.text}
                            </View>
                          );
                        })}
                      </View>
                    ) : null}
                  </View>
                </>
              ) : (
                  <View style={{ height: "500px" }}></View>
                )}
            </View>
            <View className='m-step'>
              {stepData.map((item, index) => {
                return (
                  <View className='item' key={item.step_index}>
                    <View className='step-num'>
                      <Text user-select>步骤 {index + 1}</Text>
                    </View>
                    <View className='content'>
                      {item.step_img ? (
                        <View className='step-img'>
                          <Image
                            src={item.step_img}
                            mode='widthFix'
                            lazyLoad
                          ></Image>
                        </View>
                      ) : (
                          ""
                        )}
                      <View className='step-text'>
                        <Text>{item.step_text}</Text>
                      </View>
                    </View>
                  </View>
                );
              })}
            </View>
            {tip ? (
              <View className='m-tip'>
                <Text className='title'>小贴士</Text>
                <View
                  className='taro_html'
                  dangerouslySetInnerHTML={{
                    __html: tip.replaceAll('\n', '<br>'),
                  }}
                ></View>
              </View>
            ) : null}
            {user_id !== recipeData.user_id && <View className='rate'>
              <View className='text'><Text>评价：</Text></View>
              <Rate
                value={user_score / 2}
                onChange={changeRate}
                allowHalf
                color='#ffd21e'
                voidColor='#c8c9cc'
                size={60}
              />
            </View>}
            <View className='date-heat'>
              <Text>{total_heat}人浏览过</Text>
              <Text>{create_time === update_time ? '创建于' + create_time : '更新于' + update_time}</Text>
            </View>
            <View className='hr'></View>
            <View className='m-comment'>
              <View className='title'>评论</View>
              <View className='list'>
                {commentData.length > 0 ? (
                  commentData.map((item) => {
                    const {
                      avatar,
                      children,
                      comment_id,
                      content,
                      create_time,
                      state,
                      thumbs,
                      user_id: c_user_id,
                      username,
                    } = item;
                    return (
                      <View className='item parent' key={comment_id}>
                        <View className='node'>
                          <View className='c-left'>
                            <Image src={avatar} onClick={() => handleClick('user', c_user_id, username)} />
                          </View>
                          <View className='c-right'>
                            <View className='c-name' ><Text onClick={() => handleClick('user', c_user_id, username)}>{username}</Text></View>
                            <Text className='c-date'>{create_time}</Text>
                            <View className='c-content'>
                              <Text user-select onClick={() => {
                                setInputValue({
                                  value: '',
                                  username: username,
                                  target: comment_id
                                })
                                setShowInput(true);
                              }}>
                                {content}
                              </Text>
                              {user_id === recipeData.user_id || user_id === c_user_id ? <View className='msg-del' onClick={() => delMsg(comment_id)}>删除</View> : null}
                            </View>
                            <View
                              className='c-thumbs'
                              style={{ color: state ? themeColor : "#888888" }}
                            >
                              {" "}
                              <Icon
                                name={state ? "good-job" : "good-job-o"}
                                color={state ? themeColor : "#888888"}
                                size='40'
                                onClick={() => {
                                  handleThumb(item, "father");
                                }}
                              />
                              <Text>{thumbs}</Text>
                            </View>
                          </View>
                        </View>
                        {children ? (
                          <View className='child-list' >
                            {children
                              ? children.map((item) => {
                                const {
                                  comment_id,
                                  content,
                                  create_time,
                                  p_userid,
                                  p_username,
                                  state,
                                  thumbs,
                                  user_id: c_user_id,
                                  username,
                                } = item;
                                return (
                                  <View
                                    className='item child'
                                    key={comment_id}
                                  >
                                    <View className='node'>
                                      <View className='c-right'>
                                        <View className='c-name'>
                                          <Text className='u-link' onClick={() => handleClick('user', c_user_id, username)}>
                                            {username}
                                          </Text>{" "}
                                            回复{" "}
                                          <Text className='u-link' onClick={() => handleClick('user', p_userid, p_username)}>
                                            {p_username}
                                          </Text>{" "}
                                            :
                                          </View>
                                        <Text className='c-date'>
                                          {create_time}
                                        </Text>
                                        <View
                                          className='c-content'
                                        > <Text
                                          user-select
                                          onClick={() => {
                                            setInputValue({
                                              value: '',
                                              username: username,
                                              target: comment_id
                                            })
                                            setShowInput(true);
                                          }}
                                        >
                                            {content}
                                          </Text>
                                          {user_id === recipeData.user_id || user_id === c_user_id ? <View className='msg-del' onClick={() => delMsg(comment_id)}>删除</View> : null}
                                        </View>

                                        <View
                                          className='c-thumbs'
                                          style={{
                                            color: state
                                              ? themeColor
                                              : "#888888",
                                          }}
                                        >
                                          {" "}
                                          <Icon
                                            name={
                                              state
                                                ? "good-job"
                                                : "good-job-o"
                                            }
                                            color={
                                              state ? themeColor : "#888888"
                                            }
                                            size='40'
                                            onClick={() => {
                                              handleThumb(item, "child");
                                            }}
                                          />
                                          <Text>{thumbs}</Text>
                                        </View>
                                      </View>
                                    </View>
                                  </View>
                                );
                              })
                              : null}
                          </View>
                        ) : null}
                      </View>
                    );
                  })
                ) : (
                    <Empty description='暂无评论' />
                  )}
              </View>
            </View>
          </>
        ) : null}
      </View>
    </View >
  );
};

export default memo(Index);
